/**********************************************************************************************************************
 *  -------------------------------------------------------------------------------------------------------------------
 *  file description
 *  -------------------------------------------------------------------------------------------------------------------
 *         \file  vk_type.h
 *         \unit  vkern
 *        \brief  data type definition file
 *      \details  v1.0.0
 *********************************************************************************************************************/
#ifndef __vk_type_H
#define __vk_type_H

#include "vk_config.h"

/* basic data type definition */
#ifndef uint8_t
typedef unsigned char			uint8_t;
#endif
#ifndef sint8_t
typedef signed char				sint8_t;
#endif
#ifndef uint16_t
typedef unsigned short			uint16_t;
#endif
#ifndef sint16_t
typedef signed short			sint16_t;
#endif
#ifndef uint32_t
typedef unsigned int			uint32_t;
#endif
#ifndef sint32_t
typedef signed int				sint32_t;
#endif
#ifndef uint64_t
typedef unsigned long long		uint64_t;
#endif
#ifndef sint64_t
typedef signed long long		sint64_t;
#endif
#ifndef float32_t
typedef float					float32_t;
#endif
#ifndef float64_t
typedef double					float64_t;
#endif

/* task state */
typedef enum {
	VTASK_STATE_RUNNING = 0,					/* running */
	VTASK_STATE_READY,							/* ready */
	VTASK_STATE_WAIT,							/* waittting */
	VTASK_STATE_SUSPEND,						/* suspend */
} VTASK_STATE;
typedef VTASK_STATE vtask_state_t;

/* kern error return value */
typedef enum {
	KE_OK = 0,									/* no error */
	KE_ALLOC_FAIL,								/* memory space allocation failed */
	KE_TASK_LIST_NULL,							/* task list is empty */
	KE_NO_THIS_TASK,							/* no such task */
	KE_TASK_NUM_OVER,							/* number of tasks exceeded */
	KE_TASK_ID_ERR,								/* wrong task id */
	KE_TASK_REPEAT,								/* repetitive tasks */
} KE_RET;
typedef KE_RET ke_ret_t;

/* task callback function */
typedef int (*task_handler_t)(void *data);

/* the kernel gets the time callback function */
typedef uint32_t (*vkern_tick_t)(void);

/* task type */
typedef uint32_t vtask_t;

/* task control block */ 
typedef struct {
	vtask_t task;								/* task id, unique, natural number */
	uint8_t prio;								/* task priority, a natural number, the smaller the priority, the higher the priority */
	vtask_state_t state;						/* task state */
    uint16_t period;							/* task run cycle */  
    uint16_t time;								/* task countdown */
    task_handler_t handler;						/* task callback function */
} VTCB;
typedef VTCB* vtcb_t;

/* task list node */
typedef struct _VTASK_LIST_NODE_ {
	struct _VTASK_LIST_NODE_ *next;				/* next task */
	struct _VTASK_LIST_NODE_ *prev;				/* prev task */
	vtcb_t tcb;									/* task control block */
} VTASK_LIST_NODE;
typedef VTASK_LIST_NODE* vtask_list_node_t;

/* task list */
typedef struct _VTASK_LIST {
	vtask_list_node_t head;						/* list head */
	vtask_list_node_t tail;						/* list tail */
	uint32_t len;								/* length of list */
}VTASK_LIST;
typedef VTASK_LIST* vtask_list_t;

/* kernel running state */
typedef struct {
	uint8_t state;								/* running state */
	vtask_t task;								/* id of running task */
}VKERN_RUN;
typedef VKERN_RUN vkern_run_t;

/* kernel manager */
typedef struct{
    uint32_t tick_pre;							/* previous moment */
    uint32_t tick_cur;							/* current moment */
    uint32_t task_num;							/* current number of tasks */
	vtask_list_t all_tasks;						/* list of all tasks */
	vtask_list_t ready_tasks;					/* list of ready tasks */
	vkern_run_t running;						/* kernel running state */
	uint16_t time_slice;						/* time slice length, unit ms */
	vkern_tick_t tick; 							/* get the kernel time slice callback function */
}VKERN_MANAGE;
typedef VKERN_MANAGE vkern_manage_t;

#include "comdef.h"
#if defined (KERN_USING_EXPORT) && !defined (KERN_EXPORT_NOT_SUSPORT)
typedef void (*init_handler_t)(void);
typedef struct {
    init_handler_t handler;
}init_item;

typedef struct {
    vtask_t task;
	uint8_t prio;
    uint16_t period;
    task_handler_t handler;
}task_item;

#define __initialize(func, level)                           \
    USED ANONY_TYPE(const init_item, init_item_##func)      \
    SECTION("init."level) = {func}

#define init_export(func) __initialize(func, "1")

#define task_regist_as(task, prio, period, handler)         \
    USED ANONY_TYPE(const task_item, task_item_##handler)   \
    SECTION("task.1") = {task, prio, period, handler}

#define task_regist(prio, period, handler) task_regist_as(0, prio, period, handler)

#else 

#define __initialize(func, level)
#define init_export(func)
#define task_regist_as(task, prio, period, handler)
#define task_regist(prio, period, handler)

#endif 

#endif 
